﻿/*
Created by jiadong chen
https://jiadong-chen.medium.com/
*/

Shader "chenjd/URP/ForECS_AnimMapShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_AnimMap ("AnimMap", 2D) ="white" {}
	}
	
    SubShader
    {
       Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" }
            Fog { Mode Off }
            Cull Off
            ZWrite Off
            Blend One OneMinusSrcAlpha
            Lighting Off

        Pass
        {
            Tags { "LightMode"="UniversalForward" }

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #pragma target 4.5

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct appdata
            {
                float2 uv : TEXCOORD0;
                float4 pos : POSITION;
                float4 vertexColor : COLOR;
                UNITY_VERTEX_INPUT_INSTANCE_ID                
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 vertexColor : COLOR;
                UNITY_VERTEX_INPUT_INSTANCE_ID               
            };


            CBUFFER_START(UnityPerMaterial)
                sampler2D _MainTex;
                float4 _MainTex_ST;
                sampler2D _AnimMap;
                float4 _AnimMap_TexelSize;//x == 1/width            
            CBUFFER_END 

           

            #if SHADER_TARGET >= 45
            StructuredBuffer<float4> positionBuffer;//渲染位置信息
            StructuredBuffer<float3> animeData;//x代表游戏时长，用来配合_Time.y使用，使每个动画在播放的时候是从0开始的，y代表动画状态，z代表动画速度
            #endif

            float4 fragTintedColor(float4 texColor, float3 darkTintColor, float4 lightTintColor, float darkColorAlpha) 
                {
                    float a = texColor.a * lightTintColor.a;
                    float3 texDarkColor = (texColor.a - texColor.rgb);
                    float3 darkColor = texDarkColor * darkTintColor.rgb;
                    float3 lightColor = texColor.rgb * lightTintColor.rgb;
                    float4 fragColor = float4(darkColor + lightColor, a);
                    fragColor.rgb *= fragColor.a;
                    return fragColor;
                }

            float4 ObjectToClipPos (float4 pos)
            {
                return mul (UNITY_MATRIX_VP, mul (UNITY_MATRIX_M, float4 (pos.xyz,1)));
            }
            float Remap(float input, float inputMin, float inputMax, float outputMin, float outputMax)
            {
                return outputMin + (input - inputMin) * (outputMax - outputMin) / (inputMax - inputMin);
            }



            v2f vert (appdata v, uint vid : SV_VertexID, uint instanceID : SV_InstanceID)
            {
                UNITY_SETUP_INSTANCE_ID(v);
                #if SHADER_TARGET >= 45
                 float4 pdata = positionBuffer[instanceID];
                float3 ad = animeData[instanceID] ;
                //float3 ad = float3(0,0,1) ;
                #else
                float4 pdata = 0;
                float3 ad = float3(0,0,1);
                #endif
                float4 animdata=tex2Dlod(_AnimMap, float4(_AnimMap_TexelSize.x*ad.y,0,0,0));//获取存储在纹理图第一行的动画时间信息，x代表动画时长，y代表开始位置的v值，z代表结束位置的v值

                float f =  (_Time.y-ad.x)*ad.z / animdata.x;
             

                f = fmod(f, 1);
                f = Remap(f,0,1,animdata.y+_AnimMap_TexelSize.y*1.5,animdata.z-_AnimMap_TexelSize.y*0.5);

                float animMap_x = (vid*2 + .5) * _AnimMap_TexelSize.x;
                float animMap_x_col = (vid*2 + 1.5) * _AnimMap_TexelSize.x;
                float animMap_y = f;
                
                float4 pos = tex2Dlod(_AnimMap, float4(animMap_x, animMap_y,0,0))+pdata;
                float4 col = tex2Dlod(_AnimMap, float4(animMap_x_col, animMap_y, 0, 0));


                v2f o;
                if(col.a<0){
                    o.vertexColor.a=0;
                    return o;
                    }

                UNITY_TRANSFER_INSTANCE_ID(v,o);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.vertex = ObjectToClipPos(pos);
                o.vertexColor = v.vertexColor * col;
                return o;
            }
            
            float4 frag (v2f i) : SV_Target
            {
                if( i.vertexColor.a==0)return 0;
                float4 col = tex2D(_MainTex, i.uv);
                return fragTintedColor(col, float3(0,0,0), i.vertexColor, 0);
            }
            ENDHLSL
        }
	}
}
